﻿using Microsoft.EntityFrameworkCore;
using SJ.Platform.Common;
using SJ.Platform.EFCore.Model;
using SJ.Platform.EFCore.Model.MenuManager;
using SJ.Platform.Extend.ModelExtend;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace SJ.Platform.EFCore.DBOperation.DBOperation.MySQL.Sys
{
    /// <summary>
    /// 系统菜单操作类
    /// </summary>
    public class Sys_MenuHandle
    {
        private readonly SJDBContext _context;

        public Sys_MenuHandle(SJDBContext context)
        {
            _context = context;
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<bool> CreateAsync(SysMenu entity)
        {
            try
            {
                _context.SysMenus.Add(entity);
                await _context.SaveChangesAsync();
                return true;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_MenuHandle=>Create", ex);
                return false;
            }
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<bool> UpdateAsync(SysMenu entity)
        {
            try
            {
                _context.Entry(entity).State = EntityState.Modified;
                await _context.SaveChangesAsync();
                return true;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_MenuHandle=>Update", ex);
                return false;
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool Delete(SysMenu entity)
        {
            try
            {
                _context.SysMenus.Remove(entity);
                return _context.SaveChanges() > 0;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_MenuHandle=>Delete", ex);
                return false;
            }
        }

        /// <summary>
        /// 根据主键删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<bool> DeleteByIdAsync(string id)
        {
            try
            {
                var entity = _context.SysMenus.Find(id);
                if (entity != null)
                {
                    _context.SysMenus.Remove(entity);
                    await _context.SaveChangesAsync();
                    return true;
                }
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_MenuHandle=>DeleteById", ex);
            }
            return false;
        }

        /// <summary>
        /// 根据ID获取实体
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<SysMenu> GetEntityByIdAsync(string id)
        {
            try
            {
                return await _context.SysMenus.FindAsync(id);
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_MenuHandle=>GetEntityById", ex);
            }
            return null;
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="pageNumber"></param>
        /// <param name="pageSize"></param>
        /// <param name="condition"></param>
        /// <returns></returns>
        public List<SysMenu> GetAll(int pageNumber, int pageSize, ref int count, Expression<Func<SysMenu, bool>> condition = null)
        {
            try
            {
                var query = _context.SysMenus.AsQueryable();

                // 如果提供了查询条件，则应用它
                if (condition != null)
                {
                    query = query.Where(condition);
                }
                count = query.Count();
                // 应用分页
                var skip = (pageNumber - 1) * pageSize;
                query = query.Skip(skip).Take(pageSize);

                // 执行查询并返回结果
                return query.ToList();
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_MenuHandle=>GetAll  page", ex);
            }
            return null;
        }

        /// <summary>
        /// 分页获取所有菜单
        /// </summary>
        /// <param name="pageNumber"></param>
        /// <param name="pageSize"></param>
        /// <param name="condition"></param>
        /// <returns></returns>
        public async Task<(List<SysMenuExtend> menusExt, int count)> GetAllAsync(int pageNumber, int pageSize, Expression<Func<SysMenu, bool>> condition = null)
        {
            try
            {
                var query = _context.SysMenus.AsQueryable();

                // 如果提供了查询条件，则应用它
                if (condition != null)
                {
                    query = query.Where(condition);
                }

                //总条数
                int count = await query.CountAsync();

                // 应用分页
                var skip = (pageNumber - 1) * pageSize;
                query = query.Skip(skip).Take(pageSize);

                // 执行查询并返回结果
                var menus = await query.ToListAsync();

                List<SysMenuExtend> menusExt = new List<SysMenuExtend>();
                if (menus != null && menus.Count > 0)
                {
                    menusExt = menus.Select(menu => new SysMenuExtend
                    {
                        Id = menu.Id,
                        MenuName = menu.MenuName,
                        Pid = menu.Pid,
                        Url = menu.Url,
                        Sort = menu.Sort,
                        AddTime = menu.AddTime,
                        AddUserId = menu.AddUserId,
                        EditTime = menu.EditTime,
                        EditUserId = menu.EditUserId
                    }).ToList();

                    List<string> mPId = new List<string>();
                    foreach (var m in menus)
                    {
                        if (!string.IsNullOrEmpty(m.Pid) && !mPId.Contains(m.Pid))
                        {
                            mPId.Add(m.Pid);
                        }
                    }

                    List<SysMenu> mList = _context.SysMenus.FromSqlRaw("select * FROM sys_menu where Id in ('" + string.Join("','", mPId.ToArray()) + "')").ToList();

                    foreach (SysMenuExtend menu in menusExt)
                    {
                        menu.PName = mList.Find(m => m.Id == menu.Pid) != null ? mList.Find(m => m.Id == menu.Pid).MenuName : "";
                    }
                }

                return (menusExt, count);
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_MenuHandle=>GetAllAsync  page", ex);
            }
            return (null, 0);
        }


        /// <summary>
        /// 获取所有菜单
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        public async Task<List<SysMenu>> GetAll(Expression<Func<SysMenu, bool>> condition = null)
        {
            try
            {
                IQueryable<SysMenu> query = _context.SysMenus;

                // 如果提供了查询条件，则应用它
                if (condition != null)
                {
                    query = query.Where(condition);
                }

                // 执行查询并返回结果
                return await query.ToListAsync();
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_MenuHandle=>GetAll", ex);
            }
            return null;
        }

        /// <summary>
        /// 菜单树
        /// </summary>
        /// <returns></returns>
        public async Task<List<SysMenuExtend>> GetMenuTree()
        {
            try
            {
                IQueryable<SysMenu> query = _context.SysMenus;
                var menuList = await query.OrderBy(m => m.Sort).ToListAsync();

                List<SysMenuExtend> sysMenuExtendList = new List<SysMenuExtend>();

                BuildChild(sysMenuExtendList, menuList, menuList, 1);

                return sysMenuExtendList;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_MenuHandle=>GetAll  userId", ex);
            }
            return null;
        }

        /// <summary>
        /// 根据用户ID获取菜单
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<List<SysMenuExtend>> GetAllByUserId(string userId)
        {
            try
            {
                var query = from menu in _context.SysMenus
                            join authority in _context.SysAuthorities on menu.Id equals authority.MenuId
                            join authorityToRole in _context.SysRAuthoritytoroles on authority.Id equals authorityToRole.AuthorityId
                            join role in _context.SysRoles on authorityToRole.RoleId equals role.Id
                            join foreignToRole in _context.SysRForeigntoroles.Where(e => e.ForeignType == 1) on role.Id equals foreignToRole.RoleId
                            join user in _context.SysUsers on foreignToRole.ForeignId equals user.Id
                            where user.Id == userId
                            orderby menu.Sort
                            select menu;

                var menuList = await query.ToListAsync();

                List<SysMenuExtend> sysMenuExtendList = new List<SysMenuExtend>();

                BuildChild(sysMenuExtendList, menuList, menuList, 1);

                return sysMenuExtendList;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_MenuHandle=>GetAll  userId", ex);
            }
            return null;
        }
        /// <summary>
        /// 递归生成子菜单
        /// </summary>
        /// <param name="sysMenuExtendList"></param>
        /// <param name="menuList"></param>
        /// <param name="sourceList"></param>
        /// <param name="level"></param>
        private void BuildChild(List<SysMenuExtend> sysMenuExtendList, List<SysMenu> menuList, List<SysMenu> sourceList, int level)
        {
            try
            {
                if (menuList != null && menuList.Count > 0)
                {
                    var pList = level == 1 ? menuList.Where(m => string.IsNullOrWhiteSpace(m.Pid) || m.Pid == null).ToList() : menuList;
                    foreach (var menu in pList)
                    {
                        SysMenuExtend sysMenuExtend = new SysMenuExtend();
                        sysMenuExtend.Id = menu.Id;
                        sysMenuExtend.MenuName = menu.MenuName;
                        sysMenuExtend.Pid = menu.Pid;
                        sysMenuExtend.Url = menu.Url;
                        sysMenuExtend.Sort = menu.Sort;
                        sysMenuExtend.AddUserId = menu.AddUserId;
                        sysMenuExtend.AddTime = menu.AddTime;
                        sysMenuExtend.EditTime = menu.EditTime;
                        sysMenuExtend.EditUserId = menu.EditUserId;

                        var childMenuList = sourceList.Where(c => c.Pid == menu.Id).ToList();
                        if (childMenuList != null && childMenuList.Count > 0)
                        {
                            if (sysMenuExtend.childMenuList == null)
                            {
                                sysMenuExtend.childMenuList = new List<SysMenuExtend>();
                            }
                            BuildChild(sysMenuExtend.childMenuList, childMenuList, sourceList, 2);
                        }

                        sysMenuExtendList.Add(sysMenuExtend);
                    }
                }
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Sys_MenuHandle=>BuildChild", ex);
            }
        }
    }
}